import {isEmpty, isFunction, isNumber, isString, trim} from 'lodash-es';
import dayjs, {Dayjs} from 'dayjs'
import utc from "dayjs/plugin/utc";
import weekday from 'dayjs/plugin/weekday';
import localeData from 'dayjs/plugin/localeData';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import weekYear from 'dayjs/plugin/weekYear';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import customParseFormat from "dayjs/plugin/customParseFormat";

dayjs.extend(customParseFormat);
dayjs.extend(advancedFormat);
dayjs.extend(weekday);
dayjs.extend(localeData);
dayjs.extend(weekOfYear);
dayjs.extend(weekYear);
dayjs.extend(utc);
dayjs.extend(function (o, c) {
    // todo support Wo (ISO week)
    var proto = c.prototype;
    var oldFormat = proto.format;

    proto.format = function f(formatStr) {
        var str = (formatStr || '').replace('Wo', 'wo');
        return oldFormat.bind(this)(str);
    };
});

/**
 * 当前系统的 日期格式
 * @type {string}
 */
export const curDateFormat = 'YYYY-MM-DD';
export const curDatetimeFormat = 'YYYY-MM-DD HH:mm:ss';

/**
 * 获取支持输入的日期格式，一般用于设置 DatePicker 组件的 format 属性
 * @returns {string[]}
 */
export const getDateFormats = () => (['YYYY-MM-DD', 'YYYY/MM/DD', 'YYYYMMDD', 'YYYY-M-D', 'YYYY/M/D']);

/**
 * 触发 DatePicker 组件的 Click 事件，以弹出日期选择浮层，并获得输入焦点
 * @param e Event
 * @deprecated
 */
export const triggerDateClick = (e: any) => {
    if (e && e.currentTarget) {
        let isFirst = e.currentTarget.getAttribute('isfirst');

        if ('1' !== isFirst) {
            e.currentTarget.setAttribute('isfirst', '1');

            if (e.currentTarget.childNodes && e.currentTarget.childNodes[0] &&
                e.currentTarget.childNodes[0].childNodes && e.currentTarget.childNodes[0].childNodes[0]) {
                e.currentTarget.childNodes[0].childNodes[0].click();
            }
        }

    }
};

function formatCn(cn: string) {
    return window.localUtils && window.localUtils.formatMsgByCn ? window.localUtils.formatMsgByCn(cn) : cn;
}

/**
 * 根据开始和结束期间，回显对应的中文
 * @param beginPeriod
 * @param endPeriod
 * @returns {string}
 */
// @ts-ignore
export const previewPeriod = (beginPeriod?, endPeriod?) => {
    let isEn = 'en-US' === window.localStorage.getItem('umi_locale');

    if (beginPeriod && endPeriod) {

        if (beginPeriod.name) {

            if (isEmpty(endPeriod.name)) {
                return isEn ? `From ${beginPeriod.name} to now` : `${beginPeriod.name} 至今`;

            } else if (endPeriod.name === beginPeriod.name) {
                return beginPeriod.name;

            } else {
                return isEn ? `From ${beginPeriod.name} to ${endPeriod.name}` : `${beginPeriod.name} 至 ${endPeriod.name}`;
            }

        } else if (endPeriod.name) {
            return isEn ? `${endPeriod.name} and before` : `${endPeriod.name} 及之前`;

        } else {
            return formatCn('全部');
        }
    } else {
        return formatCn('全部');
    }
};

/**
 * new 一个日期实例（dayjs 实例）
 * @param date
 * @param option
 * @param locale
 */
export function newDateIns(date?: dayjs.ConfigType, option?: dayjs.OptionType, locale?: string) {
    let tempDate = date;
    if (isNumber(tempDate) && tempDate > 0 && tempDate <= 9999999999) {
        tempDate = tempDate * 1000;
    }
    // @ts-ignore
    return dayjs(tempDate, option, locale);
}

/**
 * 判断 srcDate 是否为 Dayjs 实例
 * @param srcDate any 待判断的参数
 */
export function isDateIns(srcDate: any) {
    return srcDate && isFunction(srcDate.format);
}

/**
 * 将 srcDate 从 srcFormat 格式转成 distFormat 格式
 * @param srcDate string 当前时区的日期字符串
 * @param srcFormat string srcDate 的日期格式。默认：'YYYY-MM-DD HH:mm:ss'
 * @param distFormat string 日期格式。默认: 'YYYY-MM-DD'
 */
export function changeDateFormat(srcDate: string, srcFormat = 'YYYY-MM-DD HH:mm:ss', distFormat = 'YYYY-MM-DD') {
    let date = dayjs(srcDate, 'YYYY-MM-DD HH:mm:ss');

    if (date.isValid()) {
        return myFormatTime(dateStr2Timestamp(srcDate, srcFormat), distFormat);
    } else {
        return '';
    }
}

/**
 * 日期字符串转为时间戳
 * @param srcDate 当前时区的日期字符串或 dayjs 实例。例如：'2020-04-02 12:12:12'
 * @param format 日期格式。例如：'YYYY-MM-DD HH:mm:ss'
 * @return number
 */
export function dateStr2Timestamp(srcDate: dayjs.ConfigType, format?: string) {
    let reVal;
    if (isString(srcDate)) {
        let tzTimestamp = getTimezone() * 3600000;
        reVal = dayjs.utc(srcDate, format).valueOf() - tzTimestamp;
    } else {
        reVal = dayjs.utc(srcDate, format).valueOf();
    }

    return reVal <= 9999999999 ? reVal : Math.floor(reVal / 1000);
}

/**
 * 将 srcDate 转出 format 日期格式
 * @param timestamp string | number | Dayjs 待转换的日期
 * @param format string 日期格式。默认：'YYYY-MM-DD HH:mm:ss'
 */
export const myFormatTime = function (timestamp?: string | number | Dayjs, format = '') {
    let tempDate;
    let tzTimestamp = getTimezone() * 3600000;

    if (timestamp) {

        if (!isNumber(timestamp)) {
            timestamp = dateStr2Timestamp(timestamp);
        }

        if (timestamp > 0) {

            if (timestamp <= 9999999999) {
                timestamp = timestamp * 1000;
            }
        }

    } else {
        timestamp = +new Date();
    }

    if (null == format || '' == trim(format)) {
        format = 'YYYY-MM-DD HH:mm:ss';
    }
    tempDate = new Date(timestamp + tzTimestamp);
    return dayjs.utc(tempDate).format(format);
};

export function fixedZero(val: number) {
    return val * 1 < 10 ? `0${val}` : val;
}

/**
 * 获取时区；优先级： 缓存的时区 window.localStorage.getItem('TIMEZONE') > 系统时区
 */
export function getTimezone() {
    let sysTimezone = 0 - new Date().getTimezoneOffset() / 60;
    let timezoneStr = window.localStorage.getItem('TIMEZONE');

    if (isString(timezoneStr)) {
        let tz = parseInt(timezoneStr.replace('GMT', ''));

        if (isNumber(tz)) return tz;
        else return sysTimezone;

    } else {
        return sysTimezone;
    }
}

/**
 * 日期转周数
 * date2Week('2020-11-2')
 * @param str
 */
export function date2Week(str: string) {

    // 获取date，不传则默认为当前date，这里没有做时间格式校验
    let d = str ? new Date(str) : new Date();

    // start为1/1对应的date【0时0分】
    let start: any = new Date(d.getFullYear() + '/01/01');

    // end 为当前date【0时0分】
    let end: any = new Date(d.toLocaleDateString());

    // 天数差 【上面的0时0分意在避免影响天数的计算】
    let dayOffset = (end - start) / 1000 / 60 / 60 / 24;

    // 以周一为一周起点，故而需要加上元旦时的偏移量
    let base = dayOffset + start.getDay();
    return (
        dayOffset ? base / 7 > 52 ? dayOffset % 7 + start.getDay() ? 1 : 52 : Math.ceil(base / 7) : 1
    );
}

/**
 *  时间 显示 1分钟内显示1分钟前， 1小时内显示1小时前，1天内显示1天前，7天内显示几天前， 其他显示当前时间
 * @param timestamp
 */
export function dateTimeShow(timestamp: number){
    if(!timestamp) return null;

    // 十位数 转 13 位
    if(timestamp.toString().length === 10) timestamp = timestamp * 1000;

    let jsDate: dayjs.ConfigType | any = timestamp ? newDateIns(timestamp) : newDateIns();

    // 当前时间
    let nowDate: dayjs.ConfigType | any = newDateIns();
    if(nowDate && jsDate){
        // 时间差 的毫秒数
        let tempDate = nowDate.valueOf() - jsDate.valueOf();

        // 计算相差 天数
        let days = Math.floor(tempDate/(24*3600*1000));
        if(days >= 1 && days < 7){
            return days + "天前"
        }

        // 计算相差 小时
        let hours = Math.floor(tempDate/(3600*1000));
        if(hours >= 1 && hours < 24){
            return hours + "小时前"
        }

        // 计算相差 分钟
        let minutes = Math.floor(tempDate/(60*1000));
        if(minutes >= 1 && minutes < 60){
            return minutes + "分钟前"
        }else if(minutes < 1){
            return "1分钟前"
        }

        // 计算 相差 秒速
        let seconds = Math.floor(tempDate/(1000));
        if(seconds < 60){
            return seconds + "秒钟前"
        }
    }
    return myFormatTime(timestamp)

}
